<template>
  <section ref="refChart" class="chart_wrap" :class="className" :style="{ height: height, width: width }"></section>
</template>

<script setup>
import { onMounted, onBeforeUnmount, ref, watch, nextTick } from 'vue'
import * as echarts from 'echarts'
import { myDebounce } from '@/utils/index'

/**
 * 父组件参数
 */
const props = defineProps({
  className: {
    type: String,
    default: 'chart'
  },
  width: {
    type: String,
    default: '100%'
  },
  height: {
    type: String,
    default: '100%'
  },
  chartFontColor: {
    type: String,
    default: '#000'
  },
  autoResize: {
    type: Boolean,
    default: true
  },
  chartData: {
    type: Object,
    required: true
  },
  txtFontSize: {
    type: Number,
    default: 15
  }
})

/**
 * 定义变量
 */
let myChart = null // 图表
const refChart = ref(null) // 图表ref

let changePieInterval = null

const chartConfig = {
  barWidth: '10',
  textStyle: {
    color: '#fff',
    fontSize: 10.5,
  },
  lineStyle: {
    color: 'rgba(255, 255, 255, .6)', // 设置横坐标线颜色
    // width: 2, // 设置横坐标线宽度
  }
}

let times = 0

/**
 * 监听数据
 */
// setoption解构传参用这种监听
/* watch(
  props.chartData,
  (val) => {
    setOption(val)
  },
  { deep: true }
) */
watch(() => props.chartData, val => {
  setOption(val)
})

/**
 * 方法
 */
/**
 * 工具方法
 */
const setProxyData = (proxyData) => JSON.parse(JSON.stringify(proxyData))

const chatLoading = (flag) => {
  // console.log("loading状态", flag)
  switch (flag) {
    case "start":
      myChart.showLoading();  // 开启loading状态 开始渲染
      break;
    case "end":
      myChart.hideLoading();  // 关闭loading状态 渲染完成
      break;
  }
}

/**
 * 图表相关
 */
// 销毁图表
const destroyChart = (next) => {
  if (myChart) {
    myChart.dispose()
    myChart = null

    if (next) {
      next()
    }
  }
}
// 重置图表
const resetChart = () => {
  // console.log("初始化图表", myChart)

  destroyChart(() => {
    // 重新启动图表
    initChart()
  })
}
// 初始化图表
const initChart = () => {
  myChart = echarts.init(refChart.value, 'macarons')
  setOption(props.chartData);

  window.addEventListener('resize', myDebounce(() => {
    resetChart()
  }));
}

// 轮播
const chartAuto = (option) => {
  if (JSON.stringify(props.chartData) === '{}') {
    return
  }

  let intervaltime = 3000

  if (changePieInterval) {
    clearInterval(changePieInterval)
  }

  let currentIndex = -1; // 当前高亮图形在饼图数据中的下标
  changePieInterval = setInterval(selectChart, intervaltime); // 设置自动切换高亮图形的定时器

  // 取消所有高亮并高亮当前图形
  function highlightChart() {
    if (!myChart) {
      return
    }

    for (var idx in option.series[0].data) {
      // 遍历饼图数据，取消所有图形的高亮效果
      myChart.dispatchAction({
        type: 'showTip',
        seriesIndex: 0,
        dataIndex: idx
      });
    }
    // 高亮当前图形
    myChart.dispatchAction({
      type: 'showTip',
      seriesIndex: 0,
      dataIndex: currentIndex
    });
  }

  // 用户鼠标悬浮到某一图形时，停止自动切换并高亮鼠标悬浮的图形
  myChart.on('mouseover', (params) => {
    if (changePieInterval) {
      clearInterval(changePieInterval);
    }
    currentIndex = params.dataIndex;
    highlightChart();
  });

  // 用户鼠标移出时，重新开始自动切换
  myChart.on('mouseout', (params) => {
    if (changePieInterval) {
      clearInterval(changePieInterval);
    }
    changePieInterval = setInterval(selectChart, intervaltime);
  });

  // 高亮效果切换到下一个图形
  function selectChart() {
    if (option.series[0].data) {
      var dataLen = option.series[0].data.length;
      currentIndex = (currentIndex + 1) % dataLen;
      highlightChart();
    }
  }
}

// 设置图表
const setOption = (chartData) => {
  chatLoading('start') // 开启loading状态 开始渲染

  if (JSON.stringify(chartData) === '[]') {
    times++
    if (times > 1) {
      chatLoading('end')
    }
    return
  }

  chatLoading('end')

  // ----------------------------  图表配置开始
  const option = {
    title: {
      text: '单位(分)',
      top: "2.5%",
      right: '2%',
      textStyle: {
        color: '#fff',
        fontSize: 10,
      }
    },
    tooltip: {
      trigger: 'axis',
      textStyle: {
        color: '#000',
        fontSize: 11,
      },
      axisPointer: {
        type: 'cross',
        crossStyle: {
          color: '#fff'
        }
      }
    },
    grid: {
      left: '3%',
      right: '4%',
      bottom: '5%',
      height: '83%',
      containLabel: true
    },
    xAxis: {
      type: 'category',
      offset: 29.5,
      axisTick: {
        show: false,  // 隐藏刻度线
      },
      axisLine: {
        lineStyle: chartConfig.lineStyle
      },
      axisLabel: {
        padding: [0, 0, 0, -11],
        interval: 0, // 横轴信息全部显示
        rotate: 30,
        ...chartConfig.textStyle,
        align: 'left',
      },
      data: chartData.map(item => item.name),
    },
    yAxis: {
      type: 'value',
      splitLine: {
        show: false,
      },
      axisTick: {
        show: false,  // 隐藏刻度线
      },
      axisLine: {
        show: true, // 显示y轴线
        lineStyle: chartConfig.lineStyle
      },
      axisLabel: {
        color: '#fff',
        fontSize: 10,
      }
    },
    series: [
      {
        name: '健康度',
        type: 'line',
        barWidth: chartConfig.barWidth,
        smooth: true,
        showSymbol: false, // 在 tooltip hover 的时候显示
        itemStyle: {
          color: 'rgba(82, 217, 95, 0.8)',
        },
        lineStyle: {
          color: '#52D95F',
          width: 2, // 设置线宽
        },
        areaStyle: {
          color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
            { offset: 0, color: 'rgba(82, 217, 95, 0.3)' },
            { offset: 1, color: 'rgba(0,211,252,0)' },
          ]),
        },
        data: chartData.map(item => item.healthLevel),
      },
    ]
  }
  // ----------------------------  图表配置结束

  // 绘制图表
  myChart.setOption(option)
  // 轮播
  chartAuto(option)
}

/**
 * 生命周期
 */
onMounted(() => {
  nextTick(() => {
    initChart() // 初始化图表
  })
})
onBeforeUnmount(() => {
  destroyChart() // 销毁图表
})

/**
 * 暴露方法
 */
defineExpose({
  resetChart,
  chatLoading
})
</script>

<style lang="scss" scoped>
.chart_wrap {
  min-height: 100px;
  // cursor: pointer;
}
</style>
